#include <tchar.h>

#include "TestPlatform.h"

#include "RegistryHelper.h"
#include "ProcessInfo.h"
#include "UUIDGenerator.h"
#include "Tls.h"
#include "ThreadMemoryAllocator.h"
#include "SafeList.h"


TestPlatform::TestPlatform(void)
{
}

TestPlatform::~TestPlatform(void)
{
}


void TestPlatform::TestRegistry(void) {
	// Check existing key
	platform::RegistryHelper::RegistryKey rkey(
		platform::RegistryHelper::RK_LOCAL_MACHINE,
		_T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"));
	
	platform::XString str;
	rkey.getStringValue(_T("ProductName"), str);
	_tprintf(_T("Product Name: %s\n"), str.c_str());

	// Check new ABPA key
	platform::RegistryHelper::RegistryKey abpakey(
		platform::RegistryHelper::RK_ABPA_BASE,
		_T("Sanity\\Test"));
	abpakey.setValue(_T("ival"), 12);
	abpakey.setValue(_T("sval"), _T("value"));

}

void TestPlatform::TestProcessInfo(void) {
	platform::XString name;
	platform::ProcessInfo::GetCurrentProcessExeName(name);
	_tprintf(_T("Current Process Name: %s\n"), name.c_str());
}

void TestPlatform::TestUUID(void) {
	platform::XString id;
	platform::UUIDGenerator::Create(id);
	_tprintf(_T("UUID: %s\n"), id.getTStr());
}


struct TlsFunctor {
	void operator()(int *pi) {
		_tprintf(_T("TlsFunctor called for %d\n"), *pi);
	}
};

void tlsFunction(int *pi) {
	_tprintf(_T("TlsFunction called for %d\n"), *pi);
}

void TestPlatform::TestTls(void) {
	platform::Tls<int> tls;
	tls.set(new int(10));
	_tprintf(_T("TLS value = %d\n"), *(tls.get()));

	TlsFunctor f;
	tls.for_each(f);

	tls.for_each(tlsFunction);
}


void TestPlatform::TestThreadAllocator(void) {
	int *pi = (int*) platform::ThreadMemoryAllocator::Allocate(sizeof(int));
	_tprintf(_T("TestThreadAllocator has allocated %s pointer\n"), ((pi == NULL) ? _T("NULL") : _T("valid")));
	*pi = 10;
	platform::ThreadMemoryAllocator::Free(pi);
	_tprintf(_T("TestThreadAllocator released the memory\n"));
}


void TestPlatform::TestSafeList(void) {
	platform::SafeList<int> *plist = new platform::SafeList<int>();
	plist->push_back(new int(10));
	plist->push_back(new int(11));

	platform::SafeList<int>::OrphanElementsHandler orphHandler;

	int *pi = plist->pop_front();
	_tprintf(_T("SafeList returned element %d\n"), *pi);
	delete pi;

	plist->setOrphanElementsHandler(&orphHandler);
	delete plist;
	_tprintf(_T("OrphanList returned element %d\n"), **(orphHandler.begin()));
}